<?php

namespace Laoha\Blog\Api\Controllers;

//use App\Admin\Controllers\AppBaseController;
//use App\Admin\Forms\Grid;   //有分类，且分类设置允许自定义时，不使用use Encore\Admin\Grid是为了指定分类再新建;
//use Encore\Admin\Layout\Content;
//use Encore\Admin\Form;
//use Encore\Admin\Show;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Routing\Controller;
use App\Traits\HttpResponse;
use Laoha\Blog\Models\LaohaBlog;
use Laoha\Blog\Transformers\LaohaBlogTransformer;
//use App\Services\BaseService;
//use App\Exports\BaseExport;
//use App\QueryBuilder\BaseQueryBuilder;
use Spatie\QueryBuilder\QueryBuilder;
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\AllowedSort;
use Spatie\QueryBuilder\AllowedInclude;
//use App\Services\AppBaseService;

class LaohaBlogController extends Controller
{
    use HttpResponse;

	/**
     * Title for current resource.
     *
     * @var string
     */
    protected $app_name = 'laoha_blog';
	protected $app;
	protected $model;
	protected $includes;
	protected $filters;
	protected $sorts;
	protected $def_sort;  //默认创建日期降序排列

    # 创建构造函数,每次创建新对象时先调用此方法, 适合进行初始化
    public function __construct(Request $request)
    {
		$this->request = $request;
		$this->app=get_app($this->app_name);
		$this->model = new LaohaBlog();		
		$this->includes = ['user','cate'];
		$this->filters=[
				AllowedFilter::exact('id'),
				AllowedFilter::exact('user_id'),
				AllowedFilter::exact('cate_id'),
				'title',
				'desc',
			];		
		$this->sorts = ['id', 'cate_id','user_id','created_at'];
		$this->def_sort = '-created_at';
    }

    public function index(Request $request)
    {
$class = '\\App\\Admin\\Controllers\\Ext\\Cate';
$tempclass = get_class_methods($class);
dd($tempclass);
$ref = new \ReflectionClass($tempclass);
$methods = $ref->getMethods();     //返回类中所有方法
foreach ($methods as $method)
{
    echo $method->getName() . PHP_EOL;
}
dd($methods);
		$query = QueryBuilder::for($this->queryFor());
		$query = $this->queryIncludes($query);
		$query = $this->queryFilters($query);
		$query = $this->queryAppends($query);
		$query = $this->querySorts($query);
		$query = $query->defaultSort($this->def_sort);

        $query  = $query->paginate($request->per_page??10);  //分页
		$meta['app'] = $this->app;
		return $this->ok($query,LaohaBlogTransformer::class,$meta);
    }

	//model名或model查询，例$this->model->where('status',1)
	protected function queryFor(){
		$app_sets = $this->app['sets'] ?? [];
		$model = $this->model;
		//$q_for = $this->model->where('status',1);

		//添加queryFor		
		foreach($app_sets['tabs'] as $k=>$x){   //$k = cate; $x=exts.cate.*			
			$tempclass = config("exts.{$k}.ext") ?? '';
			if( $x && $tempclass && class_exists($tempclass) && method_exists($tempclass,'queryFor') ){
				$model = (new $tempclass())->queryFor($model,$this->app);
			}
		}
		


		if($model==$this->model){
			return get_class($this->model);
		}else{
			return $model;
		}
	}
	protected function queryIncludes($query){
		$q_includes =  $this->includes ?? [];
		if(!empty($q_includes)){
			return $query->allowedIncludes($q_includes);
		}else{
			return $query;
		}
	}

	protected function queryFilters($query){
		$app_sets = $this->app['sets'] ?? [];
		$q_filters =  $this->Filters ?? [];
		//添加queryFilters		
		foreach($app_sets['tabs'] as $k=>$x){   //$k = cate; $x=exts.cate.*			
			$tempclass = config("exts.{$k}.ext") ?? '';
			if( $x && $tempclass && class_exists($tempclass) && method_exists($tempclass,'queryFilters') ){
				$q_filters = (new $tempclass())->queryFilters($q_filters,$this->app);
			}
		}
		if(!empty($q_filters)){
			return $query->allowedFilters($q_filters);
		}else{
			return $query;
		}
	}

	protected function queryAppends($query){
		if (method_exists($this->model, 'get_appends')) {
			$q_appends =  $this->model->get_appends() ?? [];
		}
		if(!empty($q_appends)){
			return $query->allowedAppends($q_appends);
		}else{
			return $query;
		}
	}

	protected function querySorts($query){
		$q_sorts =  $this->Sorts ?? [];
		if(!empty($q_sorts)){
			return $query->allowedSorts($q_sorts);
		}else{
			return $query;
		}
	}


    public function create()
    {
        return response()->json(['data' => $this->service->create($this->request->all())]);
    }

    public function delete($id)
    {
        $this->service->delete($id);

        return response()->json();
    }

    public function show($id)
    {
        return response()->json(['data' => $this->queryBuilder->findOrFail($id)]);
    }


    public function update($id)
    {
        $model = $this->service->update($id, $this->request->all());

        return response()->json(['data' => $model]);
    }


    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
		if($cate_id = request('cate_id',0)){
			$app = get_app_cate($this->app,$cate_id);			
		}else{
			$app = get_app($this->app);
		}

		$app_sets = $app['sets'] ?? [];
		$grid = new Grid(new LaohaBlog());
		//列表前应用关联附加内容before_grid		
		foreach($app_sets['tabs'] as $k=>$x){   //$k = cate; $x=exts.cate.*			
			$tempclass = config("exts.{$k}.ext") ?? '';
			if( $x && $tempclass && class_exists($tempclass) && method_exists($tempclass,'before_grid') ){
				(new $tempclass())->before_grid($grid,$app);
			}
		}

		//回收站系列
		$trashed=request('trashed',0);
		if($trashed){
			$grid->model()->onlyTrashed();
			$grid->actions(function ($actions) {  // 添加恢复单位操作
				$actions->append(new \App\Admin\Actions\Tools\RestoreAct($actions->getKey())); 
			});

			$grid->actions(function ($actions) {
				$actions->disableDelete();
			});
		}
		$grid->tools(function ($tools){
			$tools->append(new \App\Admin\Actions\Tools\Trashed());
			if(request('trashed')){
				$tools->batch(function (\Encore\Admin\Grid\Tools\BatchActions $batch) {
					$batch->add('批量恢复', new \App\Admin\Actions\Tools\BatchRestore());
				});
			}
		});

        $grid->column('images', get_app_field_name($app,'images'))->style('width:50px')->display(function (){
			//dump($this->images);
					if($this->images){
						return "<img src='/upload/small/".$this->images[0]."' width='40' height='30' />";
					}else{
						return "<img src='/upload/small/nopic.jpg' width='40' height='30' />";
					}
				});
        $grid->column('title', get_app_field_name($app,'title'))->style('max-width:50%');
        $grid->column('user.name', __('责任人'));
        $grid->column('created_at', get_app_field_name($app,'created_at'));


		//关联附加内容grid()
		foreach($app_sets['tabs'] as $k=>$x){
			$tempclass = config("exts.{$k}.ext") ?? '';
			if( $x && $tempclass && class_exists($tempclass) && method_exists($tempclass,'grid') ){
				(new $tempclass())->grid($grid,$app);
			}
		}


		if(!empty($app['grid_selectors'])){
			$grid->selector(function (\Encore\Admin\Grid\Tools\Selector $selector) use($app){
				foreach($app['grid_selectors'] as $k=>$sel){
					$scope = $sel['scope'];
					if(!empty($sel['one'])){
						$selector->selectOne($k, $sel['title'], $sel['option'],function($query, $value) use($scope){
							return $query->$scope($value);
						});			
					}else{
						$selector->select($k, $sel['title'], $sel['option'],function($query, $value) use($scope){
							return $query->$scope($value);
						});						
					}
				}

			});
		}
        return $grid;
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     * @return Show
     */
    protected function detail($id)
    {
        $show = new Show(LaohaBlog::findOrFail($id));

        $show->field('id', __('Id'));
        $show->field('user_id', __('User id'));
        $show->field('cate_id', __('Cate id'));
        $show->field('title', __('Title'));
        $show->field('desc', __('Desc'));
        $show->field('content', __('Content'));
        $show->field('parse', __('Parse'));
        $show->field('image', __('Image'));
        $show->field('pos', __('Pos'));
        $show->field('group', __('Group'));
        $show->field('created_at', __('Created at'));
        $show->field('updated_at', __('Updated at'));

        return $show;
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
		$form = new Form(new LaohaBlog);

		$app = get_app($this->app);
		if($form->isEditing() && !empty($this->id)){				
			$rs = LaohaBlog::find($this->id);
			if(!empty($app['sets']['has_cate_sets']) && !empty($rs->cate_id)){
				$app = get_app_cate($app,$rs->cate_id);
			}
			$app['id'] = $this->id;
		}elseif($cate_id = request('cate_id',0)){
			$app = get_app_cate($app,$cate_id);
		}
		$app_sets = $app['sets'] ?? [];
		

		
//dd($app_sets);
		//附加表须有before_form()
		foreach($app_sets['tabs'] as $k=>$x){ 
			$tempclass = config("exts.{$k}.ext") ?? '';
			if( $x && $tempclass && class_exists($tempclass) && method_exists($tempclass,'before_form') ){
				(new $tempclass())->before_form($form,$app);
			}
		}
		
        $form->hidden('user_id')->default(Auth::guard('admin')->user()->user_id);

        $form->text('title', get_app_field_name($app,'title'))->required();
		if($app_sets['app']['editor']=='md'){
			$form->textarea('content', get_app_field_name($app,'content'))->help($app_sets['app']['editor']);
		}elseif($app_sets['app']['editor']=='text'){
			$form->textarea('content', get_app_field_name($app,'content'))->help($app_sets['app']['editor']);
		}else{
			$form->textarea('content', get_app_field_name($app,'content'))->help($app_sets['app']['editor']);
		}
		$form->hidden('parse', $app_sets['app']['editor']);

        //$form->image('image', get_app_field_name($app,'image'));

		if(!empty($app_sets['app']['need']['images'])){
			if($app_sets['app']['need']['images']==2){
				$form->multipleImage('images', get_app_field_name($app,'images'))->removable()->sortable()->required();
			}else{
				$form->multipleImage('images', get_app_field_name($app,'images'))->removable()->sortable();
			}
		}

		if(!empty($app_sets['app']['need']['video'])){
			if($app_sets['app']['need']['video']==2){
				$form->url('video', get_app_field_name($app,'video'))->required();
			}else{
				$form->url('video', get_app_field_name($app,'video'));
			}
		}
		if(!empty($app_sets['app']['need']['link'])){
			if($app_sets['app']['need']['link']==2){
				$form->url('link', get_app_field_name($app,'link'))->required();
			}else{
				$form->url('link', get_app_field_name($app,'link'));
			}
		}

		//附加表须有form()
		foreach($app_sets['tabs'] as $k=>$x){ 
			$tempclass = config("exts.{$k}.ext") ?? '';
			if( $x && $tempclass && class_exists($tempclass) && method_exists($tempclass,'form') ){
				(new $tempclass())->form($form,$app);
			}
		}		
        $form->datetime('created_at',get_app_field_name($app,'created_at'))->format('YYYY-MM-DD HH:mm:ss');

        return $form;
    }

    public function restore()
    {
        $ids = request('ids');
		if(!is_array($ids)) $ids = str2arr($ids);
		LaohaBlog::onlyTrashed()->find($ids)->each->restore();
    }



	//获取模型关联
	private function getAllRelations($heritage = 'all')
	{
		$model = $this->model;
		$modelName = get_class($model);
		$types = ['children' => 'Has', 'parents' => 'Belongs', 'all' => ''];
		$heritage = in_array($heritage, array_keys($types)) ? $heritage : 'all';

		$reflectionClass = new \ReflectionClass($model);

		$traits = $reflectionClass->getTraits();
		$traitMethodNames = [];
		foreach ($traits as $name => $trait) {
			$traitMethods = $trait->getMethods();
			foreach ($traitMethods as $traitMethod) {
				$traitMethodNames[] = $traitMethod->getName();
			}
		}
		$currentMethod = collect(explode('::', __METHOD__))->last();
		$filter = $types[$heritage];
		
		$methods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
		$methods = collect($methods)->filter(function ($method) use ($modelName, $traitMethodNames, $currentMethod) {
			$methodName = $method->getName();
			if (!in_array($methodName, $traitMethodNames)
				&& strpos($methodName, '__') !== 0 
				&& $method->class === $modelName
				&& !$method->isStatic() 
				&& $methodName != $currentMethod 
			) {
				$parameters = (new \ReflectionMethod($modelName, $methodName))->getParameters();
				return collect($parameters)->filter(function ($parameter) {
					return !$parameter->isOptional();
				})->isEmpty();
			}
			return false;
		})->mapWithKeys(function ($method) use ($model, $filter) {
			$methodName = $method->getName();
			$relation = $model->$methodName(); 
			if (is_subclass_of($relation, Relation::class)) {
				$type = (new ReflectionClass($relation))->getShortName(); 
				if (!$filter || strpos($type, $filter) === 0) {
					return [$methodName => ['class' => get_class($relation->getRelated()), 'relation' => get_class($relation) ] ];
				}
			}
			return [];
		})->toArray();
		return $methods;
	}
}
